package com.youshang520i;

import com.youshang520i.service.SayService;
import com.youshang520i.service.impl.SayServiceImpl;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args ) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

        // =========================第一种==========================
        // 1、生成$Proxy0的class文件
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        // 2、获取动态代理类
        Class proxyClazz = Proxy.getProxyClass(SayService.class.getClassLoader(),SayService.class);
        // 3、获得代理类的构造函数，并传入参数类型InvocationHandler.class
        Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class);
        // 4、通过构造函数来创建动态代理对象，将自定义的InvocationHandler实例传入
        SayService sayService = (SayService) constructor.newInstance(new MyInvocationHandler(new SayServiceImpl()));
        // 5、通过代理对象调用目标方法
        System.out.println(sayService.say());

        // ==========================第二种=============================
        /**
         * Proxy类中还有个将2~4步骤封装好的简便方法来创建动态代理对象，
         *其方法签名为：newProxyInstance(ClassLoader loader,Class<?>[] instance, InvocationHandler h)
         */
        SayService  sayService1 = (SayService) Proxy.newProxyInstance(SayService.class.getClassLoader(), // 加载接口的类加载器
                new Class[]{SayService.class}, // 一组接口
                new MyInvocationHandler(new SayServiceImpl())); // 自定义的InvocationHandler
        System.out.println(sayService1.say());

        System.out.println( "Hello World!" );



    }
}
